1 /*
2 * Copyright (C) 2009 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS-IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.google.common.collect;
18
19 import com.google.common.annotations.GwtCompatible;
20
21 import java.io.Serializable;
22 import java.util.Comparator;
23 import java.util.HashMap;
24 import java.util.TreeMap;
25
26 /**
27 * Contains dummy collection implementations to convince GWT that part of
28 * serializing a collection is serializing its elements.
29 *
30 * <p>Because of our use of final fields in our collections, GWT's normal
31 * heuristic for determining which classes might be serialized fails. That
32 * heuristic is, roughly speaking, to look at each parameter and return type of
33 * each RPC interface and to assume that implementations of those types might be
34 * serialized. Those types have their own dependencies -- their fields -- which
35 * are analyzed recursively and analogously.
36 *
37 * <p>For classes with final fields, GWT assumes that the class itself might be
38 * serialized but doesn't assume the same about its final fields. To work around
39 * this, we provide dummy implementations of our collections with their
40 * dependencies as non-final fields. Even though these implementations are never
41 * instantiated, they are visible to GWT when it performs its serialization
42 * analysis, and it assumes that their fields may be serialized.
43 *
44 * <p>Currently we provide dummy implementations of all the immutable
45 * collection classes necessary to support declarations like
46 * {@code ImmutableMultiset<String>} in RPC interfaces. Support for
47 * {@code ImmutableMultiset} in the interface is support for {@code Multiset},
48 * so there is nothing further to be done to support the new collection
49 * interfaces. It is not support, however, for an RPC interface in terms of
50 * {@code HashMultiset}. It is still possible to send a {@code HashMultiset}
51 * over GWT RPC; it is only the declaration of an interface in terms of
52 * {@code HashMultiset} that we haven't tried to support. (We may wish to
53 * revisit this decision in the future.)
54 *
55 * @author Chris Povirk
56 */
57 @GwtCompatible
58 // None of these classes are instantiated, let alone serialized:
59 @SuppressWarnings("serial")
60 final class GwtSerializationDependencies {
61 private GwtSerializationDependencies() {}
62
63 static final class ImmutableListMultimapDependencies<K, V>
64 extends ImmutableListMultimap<K, V> {
65 K key;
66 V value;
67
68 ImmutableListMultimapDependencies() {
69 super(null, 0);
70 }
71 }
72
73 // ImmutableMap is covered by ImmutableSortedMap/ImmutableBiMap.
74
75 // ImmutableMultimap is covered by ImmutableSetMultimap/ImmutableListMultimap.
76
77 static final class ImmutableSetMultimapDependencies<K, V>
78 extends ImmutableSetMultimap<K, V> {
79 K key;
80 V value;
81
82 ImmutableSetMultimapDependencies() {
83 super(null, 0, null);
84 }
85 }
86
87 /*
88 * We support an interface declared in terms of LinkedListMultimap because it
89 * supports entry ordering not supported by other implementations.
90 */
91 static final class LinkedListMultimapDependencies<K, V>
92 extends LinkedListMultimap<K, V> {
93 K key;
94 V value;
95
96 LinkedListMultimapDependencies() {}
97 }
98
99 static final class HashBasedTableDependencies<R, C, V>
100 extends HashBasedTable<R, C, V> {
101 HashMap<R, HashMap<C, V>> data;
102
103 HashBasedTableDependencies() {
104 super(null, null);
105 }
106 }
107
108 static final class TreeBasedTableDependencies<R, C, V>
109 extends TreeBasedTable<R, C, V> {
110 TreeMap<R, TreeMap<C, V>> data;
111
112 TreeBasedTableDependencies() {
113 super(null, null);
114 }
115 }
116
117 /*
118 * We don't normally need "implements Serializable," but we do here. That's
119 * because ImmutableTable itself is not Serializable as of this writing. We
120 * need for GWT to believe that this dummy class is serializable, or else it
121 * won't generate serialization code for R, C, and V.
122 */
123 static final class ImmutableTableDependencies<R, C, V>
124 extends SingletonImmutableTable<R, C, V> implements Serializable {
125 R rowKey;
126 C columnKey;
127 V value;
128
129 ImmutableTableDependencies() {
130 super(null, null, null);
131 }
132 }
133
134 static final class TreeMultimapDependencies<K, V>
135 extends TreeMultimap<K, V> {
136 Comparator<? super K> keyComparator;
137 Comparator<? super V> valueComparator;
138 K key;
139 V value;
140
141 TreeMultimapDependencies() {
142 super(null, null);
143 }
144 }
145 }